home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / libsock / inetserial.c < prev    next >
C/C++ Source or Header  |  1997-07-10  |  5KB  |  215 lines

  1. /* inetserial.c: Experimental interface layer to pi-port via TCP/IP
  2.  *
  3.  * Copyright (c) 1996, 1997,  D. Jeff Dionne & Kenneth Albanowski.
  4.  * This is free software, licensed under the GNU Public License V2.
  5.  * See the file COPYING for details.
  6.  */
  7.  
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <netdb.h>
  13. #include <stdio.h>
  14. #include "pi-source.h"
  15. #include "pi-socket.h"
  16. #include "pi-serial.h"
  17. #include "pi-inetserial.h"
  18. #include "pi-slp.h"
  19. #include "pi-syspkt.h"
  20. #include "pi-padp.h"
  21.  
  22. #ifdef OS2
  23. #include <sys/select.h>
  24. #endif
  25.  
  26. static int n_changebaud(struct pi_socket *ps);
  27. static int n_close(struct pi_socket *ps);
  28. static int n_write(struct pi_socket *ps);
  29. static int n_read(struct pi_socket *ps, int timeout);
  30.  
  31. int pi_inetserial_open(struct pi_socket *ps, struct sockaddr * addr, int addrlen)
  32. {
  33.   struct sockaddr_in serv_addr;
  34.   ps->mac->fd = socket(AF_INET, SOCK_STREAM, 0);
  35.   
  36.   if (addr->sa_family == AF_INET) {
  37.     memcpy(&serv_addr, addr, addrlen);
  38.   } else {
  39.     struct pi_sockaddr * pa = (struct pi_sockaddr*)addr;
  40.     memset(&serv_addr, 0, sizeof(serv_addr));
  41.     serv_addr.sin_family = AF_INET;
  42.     serv_addr.sin_addr.s_addr = inet_addr(pa->pi_device+1);
  43.     serv_addr.sin_port = htons(4386);
  44.   }
  45.  
  46.   connect(ps->mac->fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
  47.  
  48.   if (ps->sd) {
  49.     int orig = ps->mac->fd;
  50. #ifdef HAVE_DUP2
  51.     ps->mac->fd = dup2(ps->mac->fd, ps->sd);
  52. #else
  53. #ifdef F_DUPFD
  54.     close(ps->sd);
  55.     ps->mac->fd = fcntl(ps->mac->fd, F_DUPFD, ps->sd);
  56. #else
  57.     close(ps->sd);
  58.     ps->mac->fd = dup(ps->mac->fd); /* Unreliable */
  59. #endif
  60. #endif
  61.     if (ps->mac->fd != orig)
  62.       close(orig);
  63.   }
  64.  
  65. #ifndef NO_SERIAL_TRACE
  66.   if(ps->debuglog) {
  67.     ps->debugfd = open(ps->debuglog,O_WRONLY|O_CREAT|O_APPEND,0666);
  68.     /* This sequence is magic used by my trace analyzer - kja */
  69.     write(ps->debugfd, "\0\1\0\0\0\0\0\0\0\0", 10);
  70.   }
  71. #endif
  72.  
  73.   ps->serial_read = n_read;
  74.   ps->serial_write = n_write;
  75.   ps->serial_close = n_close;
  76.   ps->serial_changebaud = n_changebaud;
  77.  
  78.   return ps->mac->fd;
  79. }
  80.  
  81. static int n_changebaud(struct pi_socket *ps)
  82. {
  83.   char buffer[20];
  84.   
  85.   set_short(buffer, 1);
  86.   set_short(buffer+2, 4);
  87.   set_long(buffer+4, ps->rate);
  88.   
  89.   write(ps->mac->fd, buffer, 8);
  90.  
  91.   return 0;
  92. }
  93.  
  94. static int n_close(struct pi_socket *ps)
  95. {
  96.   int result;
  97.   char buffer[4];
  98.   
  99.   set_short(buffer, 2);
  100.   set_short(buffer+2, 0);
  101.  
  102.   write(ps->mac->fd, buffer, 4);
  103.  
  104.   result = close(ps->mac->fd);
  105.   ps->mac->fd = 0;
  106.  
  107. #ifndef NO_SERIAL_TRACE
  108.   if (ps->debugfd)
  109.     close(ps->debugfd);  
  110. #endif
  111.  
  112.   return result;
  113. }
  114.  
  115. static int n_write(struct pi_socket *ps)
  116. {
  117.   struct pi_skb *skb;
  118.   int nwrote, len;
  119.   char buffer[4];
  120. #ifndef NO_SERIAL_TRACE
  121.   int i;
  122. #endif
  123.  
  124.   if (ps->txq) {
  125.   
  126.     ps->busy++;
  127.  
  128.     skb = ps->txq;
  129.     ps->txq = skb->next;
  130.     
  131.     set_short(buffer, 0);
  132.     set_short(buffer+2, skb->len);
  133.     write(ps->mac->fd, buffer, 4);
  134.     
  135.     len = 0;
  136.     while (len<skb->len) {
  137.       nwrote = 0;
  138.       nwrote=write(ps->mac->fd,skb->data,skb->len);
  139.       if (nwrote<=0)
  140.         break; /* transmission failure */
  141.       len += nwrote;
  142.     }
  143. #ifndef NO_SERIAL_TRACE
  144.     if (ps->debuglog)
  145.       for (i=0;i<skb->len;i++) {
  146.         write(ps->debugfd, "2", 1);
  147.         write(ps->debugfd, skb->data+i, 1);
  148.       }
  149. #endif
  150.     ps->tx_bytes += skb->len;
  151.     free(skb);
  152.  
  153.     ps->busy--;
  154.     
  155.     return 1;
  156.   }
  157.   return 0;
  158. }
  159.  
  160. static int n_read(struct pi_socket *ps, int timeout)
  161. {
  162.   int r;
  163.   unsigned char *buf;
  164. #ifndef NO_SERIAL_TRACE
  165.   int i;
  166. #endif
  167.   fd_set ready,ready2;
  168.   struct timeval t;
  169.   
  170.   FD_ZERO(&ready);
  171.   FD_SET(ps->mac->fd, &ready);
  172.  
  173.   pi_serial_flush(ps);              /* We likely want to be in sync with tx */
  174.   
  175.   if (!ps->mac->expect) slp_rx(ps);  /* let SLP know we want a packet */
  176.  
  177.   while (ps->mac->expect) {
  178.     buf = ps->mac->buf;
  179.  
  180.     while (ps->mac->expect) {
  181.       ready2 = ready;
  182.       t.tv_sec = timeout/10;
  183.       t.tv_usec = (timeout % 10) * 100000;
  184.       select(ps->mac->fd+1,&ready2,0,0,&t);
  185.       /* If data is available in time, read it */
  186.       if(FD_ISSET(ps->mac->fd,&ready2))
  187.         r = read(ps->mac->fd, buf, ps->mac->expect);
  188.       else
  189.       {
  190.         /* otherwise throw out any current packet and return */
  191. #ifdef DEBUG
  192.         fprintf(stderr, "Serial RX: timeout\n");
  193. #endif
  194.         ps->mac->state = ps->mac->expect = 1;
  195.         ps->mac->buf = ps->mac->rxb->data;
  196.         ps->rx_errors++;
  197.         return 0;
  198.       }
  199. #ifndef NO_SERIAL_TRACE
  200.       if (ps->debuglog)
  201.         for (i=0;i<r;i++) {
  202.           write(ps->debugfd, "1", 1);
  203.           write(ps->debugfd, buf+i, 1);
  204.         }
  205. #endif
  206.       ps->rx_bytes += r;
  207.       buf += r;
  208.       ps->mac->expect -= r;
  209.     }
  210.     slp_rx(ps);
  211.   }
  212.   return 0;
  213. }
  214.  
  215.